package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.feign.ApArticleFeign;
import com.heima.common.contants.MQConstants;
import com.heima.common.dtos.AppHttpCodeEnum;
import com.heima.common.dtos.PageResponseResult;
import com.heima.common.dtos.ResponseResult;
import com.heima.common.exception.LeadNewsException;
import com.heima.model.wemedia.dtos.*;
import com.heima.model.wemedia.pojos.*;
import com.heima.utils.common.BeanHelper;
import com.heima.utils.common.JsonUtils;
import com.heima.utils.common.ThreadLocalUtils;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.service.WmNewsTaskService;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {
    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;
    @Autowired
    private WmMaterialMapper wmMaterialMapper;
    @Autowired
    private WmUserMapper wmUserMapper;
    @Autowired
    private WmNewsAutoScanService wmNewsAutoScanService;
    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;
    @Autowired
    private ApArticleFeign apArticleFeign;
    @Autowired
    private WmNewsMapper wmNewsMapper;
    @Autowired
    private WmNewsTaskService wmNewsTaskService;

    @Override
    public ResponseResult findList(WmNewsPageReqDto dto) {

        try {
            //参数校验
            dto.checkParam();

            //获取当前登录用户信息
            WmUser wmUser = (WmUser)ThreadLocalUtils.get();
            if(wmUser==null){
                throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
            }

            //定义查询条件
            IPage<WmNews> iPage = new Page<>(dto.getPage(),dto.getSize());
            QueryWrapper<WmNews> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id",wmUser.getId());

            //status
            if(dto.getStatus()!=null){
                queryWrapper.eq("status",dto.getStatus());
            }
            //keyword
            if(StringUtils.isNotEmpty(dto.getKeyword())){
                queryWrapper.like("title",dto.getKeyword());
            }
            //频道
            if(dto.getChannelId()!=null){
                queryWrapper.eq("channel_id",dto.getChannelId());
            }
            //发布时间
            if(dto.getBeginPubDate()!=null && dto.getEndPubDate()!=null){
                queryWrapper.between("publish_time",dto.getBeginPubDate(),dto.getEndPubDate());
            }

            //排序
            queryWrapper.orderByDesc("created_time");

            //执行查询
            iPage = page(iPage,queryWrapper);

            //获取结果进行封装
            PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(),dto.getSize(),(int)iPage.getTotal());
            pageResponseResult.setData(iPage.getRecords());
            pageResponseResult.setErrorMessage("查询成功");

            //返回结果
            return pageResponseResult;
        } finally {
            ThreadLocalUtils.remove();
        }
    }

    @Override
    public ResponseResult submit(WmNewsDto dto) {

        //获取登录用户信息
        WmUser wmUser = (WmUser)ThreadLocalUtils.get();
        if(wmUser==null){
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }

        //准备WmNews对象
        WmNews wmNews = BeanHelper.copyProperties(dto, WmNews.class);
        //设置用户ID
        wmNews.setUserId(wmUser.getId());
        //转换images格式
        if(CollectionUtils.isNotEmpty(dto.getImages())){
            /**
             * Collectors.joining(): 把每个元素使用指定分隔符拼接成新字符串
             */
            wmNews.setImages(dto.getImages().stream().collect(Collectors.joining(",")));
        }

        //处理自动封面问题
        //取出文章的content的所有图片
        List<String> contentImages = getImagesFromContent(dto.getContent());
        if(dto.getType().equals((short)-1)){
            if(contentImages.size()==0){
                //无图
                wmNews.setType((short)0);
                wmNews.setImages(null);
            }
            if(contentImages.size()>=1 && contentImages.size()<=2){
                //单图
                wmNews.setType((short)1);
                wmNews.setImages(contentImages.get(0));
            }
            if(contentImages.size()>=3){
                //三图
                wmNews.setType((short)3);
                wmNews.setImages(contentImages.subList(0,3).stream().collect(Collectors.joining(",")));
            }
        }

        //处理新增或修改文章问题
        if(dto.getId()==null){
            //新增
            wmNews.setCreatedTime(new Date());
            wmNews.setSubmitedTime(new Date());
            save(wmNews);
        }else{
            //修改
            wmNews.setSubmitedTime(new Date());
            updateById(wmNews);

            //删除该文件关联的素材引用
            QueryWrapper<WmNewsMaterial> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("news_id",dto.getId());
            wmNewsMaterialMapper.delete(queryWrapper);
        }

        //处理文章和素材关系问题
        if(dto.getStatus().equals(WmNews.Status.SUBMIT.getCode())){
            //建立文章和素材联系

            //建立内容图片和文章的引用
            //通过url查询内容素材的id
            List<Integer> contentMaterialIds = getMaterialIdsFromUrl(contentImages);
            if(CollectionUtils.isNotEmpty(contentMaterialIds)){
                wmNewsMaterialMapper.saveNewsMaterial(contentMaterialIds,wmNews.getId(),0);
            }

            //建立封面图片和文章的引用
            String coverImage = wmNews.getImages();
            if(StringUtils.isNotEmpty(coverImage)){
                List<String> coverImageUrls = Arrays.asList(coverImage.split(","));
                List<Integer> coverMaterialIds = getMaterialIdsFromUrl(coverImageUrls);
                if(CollectionUtils.isNotEmpty(coverMaterialIds)){
                    wmNewsMaterialMapper.saveNewsMaterial(coverMaterialIds,wmNews.getId(),1);
                }
            }

            //当前文章提交审核时，自动触发文章审核逻辑
            wmNewsAutoScanService.autoScanWmNews(wmNews.getId());
        }


        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    /**
     * 通过素材的url查询素材ID
     */
    private List<Integer> getMaterialIdsFromUrl(List<String> urlList){
        if(CollectionUtils.isNotEmpty(urlList)){
            QueryWrapper<WmMaterial> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("url",urlList);
            List<WmMaterial> wmMaterials = wmMaterialMapper.selectList(queryWrapper);
            return wmMaterials.stream().map(WmMaterial::getId).collect(Collectors.toList());
        }
        return null;
    }

    /**
     * 提取内容的图片路径
     * @param content
     * @return
     */
    private List<String> getImagesFromContent(String content) {
        List<String> imageList = new ArrayList<>();
        if(StringUtils.isNotEmpty(content)){
            List<Map> list = JsonUtils.toList(content,Map.class);
            for(Map map:list){
                if(map.get("type").equals("image")){
                    imageList.add((String)map.get("value"));
                }
            }
        }
        return imageList;
    }


    @Override
    public ResponseResult downOrUp(WmNewsDownUpDto dto) {
        Integer id = dto.getId();
        Short enable = dto.getEnable();

        //查询文章是否存在
        WmNews wmNews = getById(id);
        if(wmNews==null){
            throw new LeadNewsException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //判断文章是否已经发表，只有已发表的文章，才可以做上下架
        if(!wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode())){
            throw new LeadNewsException(500,"文章还未发表，请先发表！");
        }

        //更新enable状态
        wmNews.setEnable(enable);
        updateById(wmNews);

        //同步App库的文章状态
        Map<String,Object> msgMap = new HashMap<>();
        msgMap.put("articleId",wmNews.getArticleId());
        msgMap.put("enable",enable);
        //发送消息
        kafkaTemplate.send(MQConstants.WM_NEWS_UP_OR_DOWN_TOPIC,JsonUtils.toString(msgMap));

        //实现ES数据的同步
        if(enable.equals((short)1)) {
            //上架
            kafkaTemplate.send(MQConstants.WM_NEW_UP_ES_TOPIC,wmNews.getArticleId().toString());
        }else{
            //下架
            kafkaTemplate.send(MQConstants.WM_NEW_DOWN_ES_TOPIC,wmNews.getArticleId().toString());
        }


        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //删除文章
    @Override
    @GlobalTransactional
    public ResponseResult delNews(Long id) {
        if (id == null){
            throw new LeadNewsException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        WmNews news = getById(id);
        if (news == null){
            throw new LeadNewsException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //先判断文章是审核失败 2和草稿 0才能删除
        WmNews wmNews = getById(id);
        if (wmNews.getStatus() != 2 && wmNews.getStatus() != 0){
            throw new LeadNewsException(400,"文章是审核失败或草稿才能删除");
        }

        //删除news
        removeById(id);

        //审核失败才删素材
        if (wmNews.getStatus() == WmNews.Status.FAIL.getCode()){
            //删除news_material
            LambdaQueryWrapper<WmNewsMaterial> query = new LambdaQueryWrapper<>();
            query.eq(WmNewsMaterial::getNewsId,id);
            wmNewsMaterialMapper.delete(query);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

//        //同步App库的文章状态
//        Map<String,Object> msgMap = new HashMap<>();
//        msgMap.put("articleId",news.getArticleId());
//        msgMap.put("isDelete",1);  //1删除 0不删除
//        //发送消息
//        kafkaTemplate.send(MQConstants.WM_NEWS_IS_DELETE,JsonUtils.toString(msgMap));
//        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult list_vo(WmNewsAuthDto dto) {

        //定义查询条件
        IPage<WmNews> iPage = new Page<>(dto.getPage(),dto.getSize());
        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<>();
        if (dto.getStatus() != null) {
            queryWrapper.eq(WmNews::getStatus,dto.getStatus());
        }
        if (StringUtils.isNotEmpty(dto.getTitle())) {
            queryWrapper.like(WmNews::getTitle,dto.getTitle());
        }

        //排序
        queryWrapper.orderByDesc(WmNews::getCreatedTime);

        //执行查询
        iPage = page(iPage,queryWrapper);

        //转对象
        List<WmNewsNotAuthDto> wmNewsNotAuthDtos = BeanHelper.copyWithCollection(iPage.getRecords(), WmNewsNotAuthDto.class);
        for (WmNewsNotAuthDto wmNewsNotAuthDto : wmNewsNotAuthDtos) {
            Integer userId = wmNewsNotAuthDto.getUserId();
            WmUser wmUser = wmUserMapper.selectById(userId);
            wmNewsNotAuthDto.setAuthorName(wmUser.getName());
        }

        //获取结果进行封装
        PageResponseResult pageResponseResult = new PageResponseResult(dto.getPage(),dto.getSize(),(int)iPage.getTotal());
        pageResponseResult.setData(wmNewsNotAuthDtos);
        pageResponseResult.setErrorMessage("查询成功");

        //返回结果
        return pageResponseResult;
    }

    @Override
    public ResponseResult one_vo(Integer id) {
        WmNews wmNews = getById(id);
        WmNewsNotAuthDto wmNewsNotAuthDto = BeanHelper.copyProperties(wmNews, WmNewsNotAuthDto.class);
        WmUser wmUser = wmUserMapper.selectById(wmNewsNotAuthDto.getUserId());
        wmNewsNotAuthDto.setAuthorName(wmUser.getName());
        return ResponseResult.okResult(wmNewsNotAuthDto);
    }

    @Override
    public ResponseResult auth_fail(WmNewsAuthDto dto) {
        //审核失败
        WmNews wmNews = getById(dto.getId());
        //修改文章状态为2
        wmNews.setStatus(WmNews.Status.FAIL.getCode());
        wmNews.setReason("文章包含违规内容");
        updateById(wmNews);
        return ResponseResult.okResult(200,"");
    }

    @Override
    public ResponseResult auth_pass(WmNewsAuthDto dto) {
        //审核成功
        WmNews wmNews = getById(dto.getId());
        //判断发布时间如果大于当前时间，文章状态为8，暂时不发布
        if (wmNews.getPublishTime() != null && wmNews.getPublishTime().after(new Date())) {
            wmNews.setStatus(WmNews.Status.SUCCESS.getCode());
            wmNews.setReason("文章审核通过，待发表");
            wmNewsMapper.updateById(wmNews);

            //添加文章定时发布任务到延迟队列
            wmNewsTaskService.addTaskToList(wmNews);
        } else {
            //发表文章：把自媒体文章存入App文章表（调用Feign接口）
            wmNewsAutoScanService.saveApArticle(wmNews);
        }
        return ResponseResult.okResult(200,"");
    }
}
